package com.onpositive.units;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;

import org.w3c.dom.Element;

import com.onpositive.knowledge.model.values.IHasValue;

public class ParsedValueSequence extends ParsedValue {

	/**
	 * 
	 */
	private static final long serialVersionUID = 3069273149579888460L;
	public static final String ID = "value sequence" ;
	LinkedHashSet<ParsedValue> values = new LinkedHashSet<ParsedValue>();
	
	public ParsedValueSequence( String comment ){
		super(comment) ;
	} 
	
	public ParsedValueSequence( ParsedValue pv, String comment )
	{
		super( comment ) ;		
		ParsedValueSequence other = (ParsedValueSequence) pv ;
		this.values = new LinkedHashSet<ParsedValue>() ;
		for( ParsedValue oldPv : other.values ){
			try {
				ParsedValue newPv = oldPv.getClass().getConstructor( ParsedValue.class, String.class ).newInstance( oldPv, null) ;
				this.values.add(newPv) ;
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			} catch (NoSuchMethodException e) {
				e.printStackTrace();
			} catch (SecurityException e) {
				e.printStackTrace();
			}
		}
	}
	
	public ParsedValueSequence( Element element ){
		
		super(element) ;
		String str = element.getAttribute("value") ;
		String[] strArr = str.split( valueSeparator ) ;
		for( String s : strArr )
		{
			String[] strArr0 = s.split(commentSeparator) ;
			String val = strArr0[0].trim() ;
			if( val.length() == 0 )
				continue ;
			
			String comment = "" ;
			if( strArr0.length > 1 )
				comment = strArr0[1].trim() ;
			
			values.add( new ParsedString( val,comment ) ) ;
		}
	}
	
//	public ParsedValueSequence( ParsedValue pv, String comment )
//	{
//		super(comment) ;
//		addValue(pv) ;
//	}
	
	public ParsedValueSequence( Iterable<? extends ParsedValue> pv, String comment  )
	{
		super(comment) ;
		addValues(pv) ;
	}
/*  it's not clear, what is the comment for ParsedString(string,comment) constructor.
 *  so this ParsedValueSequence() constructor is disabled
 *  	
	public ParsedValueSequence( String str, String comment )
	{
		super(comment) ;
		String[] split = str.split( valueSeparator ) ;
		for( String s : split )
			if( s.trim().length() != 0 )
				addValue( new ParsedString( s.trim() ) ) ;
	}
*/	
	
	@Override
	public Object value() {
		
		return values;
	}

	@Override
	public void setValue(Object obj) {}

	@Override
	public Object describer() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String getId() {

		return ID;
	}

	//public static String valueSeparator2 = "\\*#\\*" ;
	public static String valueSeparator = "#####" ;
	public static String commentSeparator = "#c#" ;
	@Override
	public String getValueAsString() {
		
		StringBuilder builder = new StringBuilder() ;
		
		if( values.size() == 0 )
			return "" ;
		
		for( ParsedValue pv : values )
		{
			builder.append( pv.getValueAsString() ) ;			
			final String comment = pv.getComment();
			
//			if( comment != null && comment.length() != 0 ){
//				builder.append( commentSeparator ) ;
//				builder.append( comment ) ;
//			}
			
			builder.append( valueSeparator ) ;
		}
		builder.delete( builder.length() - valueSeparator.length(), builder.length() ) ;
		return builder.toString();
	}
	
	public void addValue( ParsedValue pv )
	{
		values.add(pv) ;
	}
	
	public void addValues( Iterable<? extends ParsedValue> pvit )
	{
		for( ParsedValue pv : pvit )
			values.add(pv) ;
	}
	
	public void removeValue( ParsedValue pv )
	{
		values.remove(pv) ;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((values == null) ? 0 : values.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		ParsedValueSequence other = (ParsedValueSequence) obj;
		if (values == null) {
			if (other.values != null)
				return false;
		} else if (!values.equals(other.values))
			return false;
		return true;
	}

	public int size() {		
		return values.size();
	}

	@Override
	public IHasValue clone(Object value, String comment) {
		return null;
	}

	@Override
	public <T> Collection<T> getValues(Class<T> vs) {
		HashSet<T>vm=new HashSet<T>();
		for (ParsedValue v: this.values){
			if (vs.isInstance(v)){
				vm.add(vs.cast(v) );
			}
			vm.addAll(v.getValues(vs));
		}
		return vm;
	}



}
